package cn.amebius.simpledocker.websocket;

import cn.amebius.simpledocker.config.DockerFactory;
import cn.amebius.simpledocker.entity.model.DockerClientModel;
import cn.amebius.simpledocker.thread.AttachConsoleThread;
import cn.amebius.simpledocker.thread.TerminalThread;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.api.model.Frame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.PostConstruct;
import java.io.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 阿伟
 * @date 2023/9/12 22:54
 */
@Slf4j
@Component
public class ContainerTerminalWebSocketHandler extends BaseAbstractWebsocket {

    private static ConcurrentHashMap<WebSocketSession, PipedOutputStream> userMap;

    private static ConcurrentHashMap<PipedOutputStream, TerminalThread> threadMap;

    private InputStream in;

    private OutputStream out;

    @Autowired
    public void setService(DockerFactory dockerFactory) {
        ContainerTerminalWebSocketHandler.userMap = new ConcurrentHashMap<>();
        ContainerTerminalWebSocketHandler.threadMap = new ConcurrentHashMap<>();
    }

    // 连接建立时触发
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws IOException {
        PipedInputStream pipedInputStream = new PipedInputStream();
        PipedOutputStream pipedOutputStream = new PipedOutputStream();
        pipedInputStream.connect(pipedOutputStream);
        userMap.put(session,pipedOutputStream);
        log.info("【ContainerTerminalWs】连接:{}",session.getRemoteAddress());
        log.info("【ContainerTerminalWs】连接数：{}", ContainerTerminalWebSocketHandler.userMap.size());

        String containerId = (String) session.getAttributes().get("containerId");

        DockerClient dc = getDockerClient(session);
//        TerminalThread tt = new TerminalThread(session,getInput(session.getId()),dc,containerId,getOutput(session.getId()));
//        threadMap.put(pipedOutputStream,tt);
//        tt.start();
        initIOs(session.getId());
        OutputStream output = getOutput(session.getId());
        InputStream input = getInput(session.getId());
        ExecCreateCmdResponse execCreateCmdResponse = dc.execCreateCmd(containerId)
                .withCmd("bash")
                .withAttachStdin(true)
                .withAttachStdout(true)
                .exec();
        String execId = execCreateCmdResponse.getId();
        dc.execStartCmd(execId)
                .withDetach(false)
                .withTty(true)
                .withStdIn(input)
                .exec(new ResultCallback<Frame>() {
                    @Override
                    public void onStart(Closeable closeable) {
                        System.out.println("开启！");
                    }
                    @Override
                    public void onNext(Frame frame) {
                        System.out.println("输出输出输出");
                        try {
                            session.sendMessage(new TextMessage(frame.getPayload()));
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    @Override
                    public void onError(Throwable throwable) {

                    }
                    @Override
                    public void onComplete() {

                    }
                    @Override
                    public void close() throws IOException {

                    }
                });

    }
    // 处理收到的文本消息
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        PipedOutputStream inputStream = userMap.get(session);
        OutputStream output = getOutput(session.getId());
        String msg = message.getPayload();
        log.info("shurushurushru:{}",msg);

        log.info("{}", message.asBytes());
        inputStream.write(msg.getBytes());
        output.write(msg.getBytes());
        if (message.asBytes().equals(new byte[]{13})) {
            output.flush();
            inputStream.flush();
        }

    }

    // 连接关闭时触发
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws IOException {
        PipedOutputStream pipedOutputStream = userMap.get(session);
        pipedOutputStream.close();
        userMap.remove(session);
        TerminalThread tt = threadMap.get(pipedOutputStream);
        tt.interrupt();
        threadMap.remove(pipedOutputStream);
        log.info("【ContainerTerminalWs】退出：{}",session.getRemoteAddress());
        log.info("【ContainerTerminalWs】连接数：{}", userMap.size());
    }

}
